#include <vector>
#include <pthread.h>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iostream>
//一个简单的线程池先只考虑“临界资源保护”、“线程的正常创建”

class Task
{
public:
    void* (*func)(void *args);
    void* args;
};

class PthreadPool
{
public:
    std::queue<Task> tasks;
    std::vector<pthread_t> pthreadpool;
    std::mutex mtx;
    std::condition_variable cond;
    bool IsRunning = true;
public:
    PthreadPool(const int& thread_num)
    {
        InitPool(thread_num);
    }
    ~PthreadPool()
    {
        DestroyPool();
    }

    static void *ThreadLoop(void* args)
    {
        PthreadPool* self = static_cast<PthreadPool*>(args);
        while(1)
        {
            Task task;
            {
                std::unique_lock<std::mutex> lock(self->mtx);
                // 等待任务或线程池关闭
                self->cond.wait(lock, [self] { return !self->IsRunning||!self->tasks.empty(); });
                if (!self->IsRunning && self->tasks.empty())
                {
                    std::cout << "线程将要退出" << std::endl;
                    break;
                }
                // 提取任务
                task = self->tasks.front();
                self->tasks.pop();
            }
            // 执行任务，释放互斥锁
            task.func(task.args);
        }
        return nullptr;
    }

    void InitPool(const int& thread_num)
    {
        for(int i=0;i<thread_num;i++)
        {
            pthread_t tid;
            pthread_create(&tid,nullptr,ThreadLoop,this);
            pthreadpool.push_back(tid);
            std::cout<<"创建线程"<<std::endl;
            //安全检查TODO
        }
    }

    void AddTask(const Task& task)
    {
        std::unique_lock<std::mutex> lock(mtx);
        tasks.push(task);
        lock.unlock();
        cond.notify_one();
    }

    void DestroyPool()
    {  
        {
            std::unique_lock<std::mutex> lock(mtx);
            IsRunning=false;
        }
        cond.notify_all();
        for(auto& e:pthreadpool)
        {
            pthread_join(e,nullptr);
            std::cout<<"回收线程"<<std::endl;
        }
    }
};